package com.ruoyi.monitor.utils;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.bean.BeanUtils;
//import com.ruoyi.monitor.model.Observer.SMSObserver;
import com.ruoyi.monitor.Vo.CityVo;
import com.ruoyi.monitor.Vo.PollutantVo;
import com.ruoyi.monitor.domain.Pollutant;
import com.ruoyi.monitor.domain.PollutantAvg;
import com.ruoyi.monitor.model.Observer.QualityObserver;
import com.ruoyi.monitor.model.Subject.QualitySubject;
import com.ruoyi.monitor.service.IPolluantAvgService;
import com.ruoyi.monitor.service.IPollutantService;
import com.ruoyi.monitor.utils.Common.Constant;
import com.ruoyi.monitor.utils.Common.DateUtils;
import com.ruoyi.monitor.utils.Common.HttpUtils;
import com.ruoyi.system.service.ISysMenuService;
import org.apache.http.HttpResponse;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 数据获取中心
 *
 */
@Component("api")
public class APICenter {
    @Autowired
    private IPollutantService pollutantService;
    @Autowired
    private IPolluantAvgService polluantAvgService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private QualitySubject subject;
    @Autowired
    private QualityObserver observer;
    @Autowired
    private ISysMenuService menuService;

    private static Logger logger = Logger.getLogger(APICenter.class);
    @PostConstruct
    public void initData(){
        saveData();
        List<CityVo> cityVoList = getRankData();
        if (!ObjectUtil.isEmpty(cityVoList))
        {
            redisCache.setCacheList("rank",cityVoList);
            redisCache.expire("rank",30, TimeUnit.MINUTES);
        }
    }


    public List<CityVo> getRankData(){
        String host = Constant.HOST;
        String path = Constant.RANKPATH;
        String method = Constant.GET;
        String appcode = Constant.APPCODE;
        InputStream content = null;
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<String, String>();
        StringBuilder data = new StringBuilder();
        try {
            HttpResponse response = HttpUtils.doGet(host, path, method, headers, querys);
            System.out.println(response.toString());
            content = response.getEntity().getContent();
            try(BufferedReader reader = new BufferedReader(new InputStreamReader(content))) {
                String c ;
                while ((c=reader.readLine())!=null){
                    data.append(c);
                    data.append(System.getProperty("line.separator"));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            //获取response的body
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (data.length()==0) return null;
        return (List<CityVo>) transferJSON(Constant.CITY, data.toString());

    }

//    @Scheduled(cron = "0 0 */1 * * ? ")

    /**
     * 定时获取API数据
     */
    public void saveData(){
        logger.info("数据获取启动");
        Pollutant apiData = getPollutantData(Constant.city);
        System.out.println(apiData);
        if (!ObjectUtil.isEmpty(apiData)){
            logger.info("当前城市:"+Constant.city);
            //开关，第一次开启会发送一次
            redisCache.setCacheObject("latest",apiData);
            long between = DateUtil.between(new Date(), apiData.getCt(), DateUnit.HOUR);
            logger.info("时间差"+between);
            if (ObjectUtil.isEmpty(pollutantService.findPollutant(apiData)) &&
                    DateUtil.between(new Date(),apiData.getCt(), DateUnit.HOUR)>=1){
                //如果自动发送功能开启就发送
//            String auto = redisCache.getCacheObject("autoSend");
//            if (ObjectUtil.isEmpty(auto)){
//                auto = "0";
//                redisCache.setCacheObject("autoSend",auto);
//            }
//            if ("0".equals(auto)){
//                logger.info("自动发送功能开启");
//                sendNotification(apiData);
//            }else {
//                logger.info("自动发送功能已关闭");
//            }

                pollutantService.insertPollutant(apiData);
        }else {
                logger.warn("接口调用失败");
            }


            Pollutant avgDay = pollutantService.CountAVGDay();
            PollutantAvg avg = new PollutantAvg();
            BeanUtils.copyProperties(avgDay,avg);

            avg.setId(null);
            DateTime beginOfDay = DateUtil.beginOfDay(avgDay.getCt());
            avg.setStart(beginOfDay);
            DateTime endOfDay = DateUtil.endOfDay(avgDay.getCt());
            avg.setEnd(DateUtils.get0MIll(endOfDay));
            logger.info("日均值生成:"+avg);
            avg.setType(Constant.DAILY);
            polluantAvgService.saveOrUpdate(avg,new UpdateWrapper<PollutantAvg>().apply("start = "+ "'"+DateUtils.format(beginOfDay)+ "'")
                    .apply("end = "+ "'"+DateUtils.format(endOfDay)+ "'").eq("type",Constant.DAILY).eq("area",Constant.city));
            logger.info("...日均值入库完成");
            DateTime beginOfWeek = DateUtil.beginOfWeek(avgDay.getCt());
            DateTime endOfWeek = DateUtil.endOfWeek(avgDay.getCt());
            PollutantAvg weekLatest = polluantAvgService.countAVGWeekLatest();
            logger.info("周均值生成:"+weekLatest);
            polluantAvgService.saveOrUpdate(weekLatest,new UpdateWrapper<PollutantAvg>().apply("start = "+ "'"+DateUtils.format(beginOfWeek)+ "'")
                    .apply("end = "+ "'"+DateUtils.format(endOfWeek)+ "'").eq("type",Constant.WEEKLY).eq("area",Constant.city));
            logger.info("...周均值入库完成");
            DateTime beginOfMonth = DateUtil.beginOfMonth(avgDay.getCt());
            DateTime endOfMonth = DateUtil.endOfMonth(avgDay.getCt());
            PollutantAvg monthLatest = polluantAvgService.countAVGMonthLatest();
            logger.info("月均值生成:"+weekLatest);
            polluantAvgService.saveOrUpdate(monthLatest,new UpdateWrapper<PollutantAvg>().apply("start = "+ "'"+DateUtils.format(beginOfMonth)+ "'")
                    .apply("end = "+ "'"+DateUtils.format(endOfMonth)+ "'").eq("type",Constant.MONTHLY).eq("area",Constant.city));
            logger.info("...月均值入库完成");
        }else {
            logger.warn("当前时间段数据已存在");
        }
    }

    public void sendNotification(Pollutant apiData){
        subject.registerObserver(observer);
        subject.setPollutant(apiData);
    }

    public Pollutant getPollutantData(String city){
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + Constant.APPCODE);
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("city", city);
        Pollutant pollutant = new Pollutant();
        try {
            HttpResponse response = HttpUtils.doGet(Constant.HOST, Constant.DETAILPATH, Constant.GET, headers, querys);
            InputStream content = response.getEntity().getContent();
            StringBuilder data = new StringBuilder();
            try(BufferedReader reader = new BufferedReader(new InputStreamReader(content))) {
                String c ;
                while ((c=reader.readLine())!=null){
                    data.append(c);
                    data.append(System.getProperty("line.separator"));
                }
//                System.out.println(data);

            }
            if (data.length()!=0){
                PollutantVo pollutantVo = (PollutantVo) this.transferJSON(Constant.POLLUTANT,data.toString());
                BeanUtils.copyProperties(pollutantVo,pollutant);
                pollutant.setPrimary_pollutant(pollutantVo.getPrimary_pollutant());
                pollutant.setCt(DateUtils.trans(pollutantVo.getCt()));
                pollutant.setPm25(pollutantVo.getPm2_5());
                pollutant.setAreaCode(pollutantVo.getArea_code());
                pollutant.setO38h(pollutantVo.getO3_8h());

                Constant.areaCode = pollutantVo.getArea_code();
                logger.info("数据对象生成:"+pollutant);
            }else {
                logger.warn("接口调用失败");
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pollutant;
    }


    //JSON数据转对象
    public Object transferJSON(String dataType,String content){
        Object res = null;
        ObjectMapper mapper = new ObjectMapper();

        if (Constant.POLLUTANT.equals(dataType)){
            PollutantVo pollutantVo = new PollutantVo();
            try {
                JsonNode jsonNode = mapper.readTree(content);
                JsonNode path = jsonNode.path("showapi_res_body");
                JsonNode pm = path.path("pm");
                String all=pm.toString();
                if (all.contains("\"_\"")){
                    all = pm.toString().replaceAll("\"_\"", "\"0\"");
                }
                System.out.println(all);
                pollutantVo = JSON.parseObject(all, PollutantVo.class);
            } catch (JsonProcessingException e) {
                logger.info("error of api");
                e.printStackTrace();
            }
            logger.info("数据生成成功");
            res = pollutantVo;
        }else if (Constant.CITY.equals(dataType)){
            List<CityVo> cityVoList = null;
            try {
                JsonNode jsonNode = mapper.readTree(content);
                JsonNode path = jsonNode.path("showapi_res_body");
                JsonNode pm = path.path("list");
                String all = pm.toString();
                if (all.contains("\"_\"")){
                    all = pm.toString().replaceAll("\"_\"", "\"0\"");
                }
                cityVoList = JSONObject.parseObject(all,new TypeReference<List<CityVo>>(){});
                cityVoList.forEach(cityVo -> {
                    if ("".equals(cityVo.getPrimary_pollutant())){
                        cityVo.setPrimary_pollutant("-");
                    }
                });
                System.out.println("after:"+cityVoList);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            res = cityVoList;
        }
        return res;
    }


}
